package com.hxrfid.web.controller.project;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.hxrfid.common.annotation.Log;
import com.hxrfid.common.annotation.RepeatSubmit;
import com.hxrfid.common.config.LogisticeConfig;
import com.hxrfid.common.core.controller.BaseController;
import com.hxrfid.common.core.domain.PageQuery;
import com.hxrfid.common.core.domain.R;
import com.hxrfid.common.core.page.TableDataInfo;
import com.hxrfid.common.core.validate.AddGroup;
import com.hxrfid.common.core.validate.EditGroup;
import com.hxrfid.common.enums.BusinessType;
import com.hxrfid.common.enums.OrderStatusEnum;
import com.hxrfid.common.utils.SignUtils;
import com.hxrfid.common.utils.poi.ExcelUtil;
import com.hxrfid.project.domain.BsOrder;
import com.hxrfid.project.domain.LogisticsRes;
import com.hxrfid.project.domain.QueryTrackParam;
import com.hxrfid.project.domain.QueryTrackReq;
import com.hxrfid.project.domain.bo.BsOrderBo;
import com.hxrfid.project.domain.bo.BsOrderProductBo;
import com.hxrfid.project.domain.vo.BsOrderVo;
import com.hxrfid.project.domain.vo.MyBsOrderVo;
import com.hxrfid.project.service.IBsOrderService;
import com.hxrfid.system.service.ISysDictDataService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 订单管理
 *
 * @author hxrfid
 * @date 2025-06-12
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/project/order")
public class BsOrderController extends BaseController {

    private final IBsOrderService iBsOrderService;
    private final LogisticeConfig logisticeConfig;
    private final ISysDictDataService sysDictDataService;

    /**
     * 查询购物车列表
     */
    @GetMapping("/listCart")
    public TableDataInfo<BsOrderVo> listCart(BsOrderBo bo, PageQuery pageQuery) {
        bo.setOrderStatus(OrderStatusEnum.ZERO.getCode());
        return iBsOrderService.queryPageList(bo, pageQuery);
    }

    /**
     * 查询订单管理列表
     */
    @GetMapping("/list")
    public TableDataInfo<BsOrderVo> list(BsOrderBo bo, PageQuery pageQuery) {
        return iBsOrderService.queryPageList(bo, pageQuery);
    }

    /**
     * 查询子用户列表
     */
    @GetMapping("/listChild")
    public TableDataInfo<MyBsOrderVo> listChild(BsOrderBo bo, PageQuery pageQuery) {
        return iBsOrderService.queryPageListChild(bo, pageQuery);
    }

    /**
     * 导出订单管理列表
     */
    @Log(title = "订单管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(BsOrderBo bo, HttpServletResponse response) {
        List<BsOrderVo> list = iBsOrderService.queryList(bo);
        ExcelUtil.exportExcel(list, "订单管理", BsOrderVo.class, response);
    }

    /**
     * 导出子用户列表
     */
    @Log(title = "订单管理", businessType = BusinessType.EXPORT)
    @PostMapping("/exportChild")
    public void exportChild(BsOrderBo bo, HttpServletResponse response) {
        TableDataInfo<MyBsOrderVo> tableDataInfo = iBsOrderService.queryPageListChild(bo, new PageQuery());
        List<MyBsOrderVo> list = tableDataInfo.getRows();
        ExcelUtil.exportExcel(list, "子用户订单", MyBsOrderVo.class, response);
    }

    /**
     * 获取订单管理详细信息
     *
     * @param id 主键
     */
    @GetMapping("/{id}")
    public R<BsOrderVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Long id) {
        return R.ok(iBsOrderService.queryById(id));
    }

    /**
     * 获取订单管理详细信息
     *
     * @param id 订单编号
     */
    @GetMapping("/detail/{id}")
    public R<BsOrderVo> getDetailInfo(@PathVariable String id) {
        return R.ok(iBsOrderService.queryByOrderNo(id));
    }

    /**
     * 获取订单支付金额
     */
    @RepeatSubmit()
    @PostMapping("/getMoney")
    public R<BsOrderBo> getMoney(@RequestBody BsOrderBo bo) {
        return R.ok(iBsOrderService.getMoney(bo));
    }

    /**
     * 购物车
     */
    @Log(title = "订单管理", businessType = BusinessType.UPDATE)
    @PostMapping("/editCart")
    public R<BsOrderBo> editCart(@Validated(AddGroup.class) @RequestBody BsOrderBo bo) {
        return R.ok(iBsOrderService.editCart(bo));
    }

    /**
     * 购物车转订单
     */
    @Log(title = "订单管理", businessType = BusinessType.UPDATE)
    @PostMapping("/transferCart")
    public R<Void> transferCart(@Validated(AddGroup.class) @RequestBody BsOrderBo bo) {
        return toAjax(iBsOrderService.transferCart(bo));
    }

    /**
     * 新增订单管理
     */
    @Log(title = "订单管理", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<BsOrder> add(@Validated(AddGroup.class) @RequestBody BsOrderBo bo) {
        return R.ok(iBsOrderService.insertByBo(bo));
    }

    /**
     * 修改订单管理
     */
    @Log(title = "订单管理", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody BsOrderBo bo) {
        return toAjax(iBsOrderService.updateByBo(bo) ? 1 : 0);
    }

    /**
     * 订单发货
     */
    @Log(title = "订单管理", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping("/send")
    public R<Void> send(@Validated(EditGroup.class) @RequestBody BsOrderBo bo) {
        return toAjax(iBsOrderService.sendByBo(bo) ? 1 : 0);
    }

    /**
     * 删除订单管理
     *
     * @param ids 主键串
     */
    @Log(title = "订单管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(iBsOrderService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
    }

    /**
     * 删除成员绑定关系
     *
     * @param userId 成员ID
     */
    @Log(title = "订单管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/delChildOrder/{userId}")
    public R<Void> delChildOrder(@NotNull(message = "成员ID不能为空")
                          @PathVariable Long userId) {
        return toAjax(iBsOrderService.delChildOrder(userId) ? 1 : 0);
    }

    /**
     * 查询物流信息
     * @param bo 物流编号
     */
    @SaIgnore
    @GetMapping("/listLogistics")
    public R<List<LogisticsRes>> listLogistics(BsOrderBo bo) {
        // 查询快递公司
        String logisticsFirm = sysDictDataService.selectDictLabel("logistics_firm", bo.getLogisticsFirm());

        QueryTrackParam param = new QueryTrackParam();
        param.setCom(bo.getLogisticsFirm());
        param.setNum(bo.getLogisticsNo());
        if (logisticsFirm.contains("顺丰")) {
            param.setPhone(bo.getPhone());
        }
        // 查询订单
        String string = JSONUtil.toJsonStr(param);
        String sign = SignUtils.querySign(string, logisticeConfig.getKey(), logisticeConfig.getCustomer());
        QueryTrackReq req = new QueryTrackReq();
        req.setCustomer(logisticeConfig.getCustomer());
        req.setParam(string);
        req.setSign(sign);

        // 创建表单数据映射
        MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
        formData.add("customer", req.getCustomer());
        formData.add("param", req.getParam());
        formData.add("sign", req.getSign());

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); // 设置内容类型
        // 封装请求
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);

        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> res = restTemplate.postForEntity(logisticeConfig.getUrl(), requestEntity, String.class);
        JSONObject jsonObject = JSONUtil.parseObj(res.getBody());
        if (ObjectUtil.isNotNull(jsonObject.get("data"))) {
            List<LogisticsRes> list = JSONUtil.toList(jsonObject.get("data").toString(), LogisticsRes.class);
            return R.ok(list);
        } else {
            return R.fail(String.format("该【%s】单号暂时未能同步到物流信息，可能该公司物流系统延迟或单号查询报错。建议您：复制单号 【%s】去【%s】官网查询", logisticsFirm, bo.getLogisticsNo(), logisticsFirm));
        }
    }

    /**
     * 微信退款
      */
    @PostMapping("/refund")
    public R<Void> refund(@RequestBody BsOrderBo bo) {
        return toAjax(iBsOrderService.refund(bo));
    }

    /**
     * 创建微信支付
     */
    @PostMapping("/createWxPay")
    public R<Map<String, Object>> createWxPay(@RequestBody BsOrderBo bo) {
        return R.ok(iBsOrderService.createWxPay(bo));
    }

    /**
     * 校验商品库存
     */
    @Log(title = "订单管理", businessType = BusinessType.INSERT)
    @PostMapping("/checkInventory")
    public R<String> checkInventory(@RequestBody List<BsOrderProductBo> details) {
        return R.ok(iBsOrderService.checkInventory(details));
    }
}
